package com.example.common.core.domain;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2025-02-11
 * Time: 13:35
 */

import com.example.common.core.enums.ResultCode;
import lombok.Getter;
import lombok.Setter;

/**
 * 抽象出来做一个公共的相应式数据, 包含状态码, 返回消息以及返回数据
 * @param <T> 由于返回数据不同接口是不同的, 因此采用泛型
 */
@Getter
@Setter
public class R<T> {

    private int code; // 状态码

    private String msg; // code 对应的返回消息

    private T date;  // 返回数据

    /**
     * 根据设计后发现, 通常返回的消息分为 date 和状态码以及对应状态信息(被封装为了 ResultCode 对象), 因此构造一个泛型返回方法
     * @param date 返回数据
     * @param resultCode 封装的返回数据
     * @param <T> 传入一个泛型参数
     * @return 返回一个泛型对象 <T>
     */
    // 提供几个统一的常用异常处理
    public static <T> R<T> assembleResult(T date, ResultCode resultCode) {
        R<T> r = new R<>();
        r.setCode(resultCode.getCode());
        r.setMsg(resultCode.getMsg());
        r.setDate(date);
        return r;
    }

    // 根据封装的泛型方法, 重构两个常用的返回消息的方法
    // 由于 R 是定义成一个异常消息响应类型, 可以提供几个重载的方法
    // 1. 表示请求成功, 无需返回信息, 只需要设置状态码即可
    public static <T> R<T> ok() {
        return assembleResult(null, ResultCode.SUCCESS);
    }

    // 2. 表示请求失败, 提供失败的状态码和提示信息
    // 操作失败了, 但服务端没有异常, 统一只返回 " 操作失败 ", 数据看需求返回
    public static <T> R<T> fail (T date) {
        return assembleResult(date, ResultCode.FAILED);
    }

    // 3. 表示请求失败, 提供失的状态码和提示信息
    // 操作没失败, 但是服务器出了问题, 但是不需要信息返回去提示给用户, 只需要设置错误的状态码和对应的信息供研发查看即可
    /**
     * 根据具体需求提供指定的错误码和错误信息
     * @param resultCode 封装好的泛型对象
     * @return 返回一个泛型参数
     * @param <T> 需要传入一个泛型参数
     */
    public static <T> R<T> fail (ResultCode resultCode) {
        return assembleResult(null, resultCode);
    }
}
